﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DAL.Engine.Domain;

namespace DAL.Engine.Test
{
    [TestClass]
    public class EntityTest
    {
        #region Test Equals

        [TestMethod]
        public void TestStringEquals()
        {
            // Arrange
            var arrange = GenerateEntities("1", "1 ", "", "1");

            // Act            
            var actual1 = arrange[0].Equals(arrange[0]);
            var actual2 = arrange[0].Equals(null);
            var actual3 = arrange[0].Equals(arrange[2]);
            var actual4 = arrange[0].Equals(arrange[3]);

            // Assert
            Assert.IsTrue(actual1);
            Assert.IsFalse(actual2);
            Assert.IsFalse(actual3);
            Assert.IsTrue(actual4);
        }

        [TestMethod]
        public void TestGuidEquals()
        {
            // Arrange
            var id = Guid.Parse("406767AC-D418-4899-A06D-75AF27F1A3F0");
            var arrange = GenerateEntities(Guid.Empty, id, id, Guid.NewGuid());

            // Act            
            var actual1 = arrange[0].Equals(arrange[0]);
            var actual2 = arrange[0].Equals(null);
            var actual3 = arrange[1].Equals(arrange[2]);
            var actual4 = arrange[1].Equals(arrange[3]);

            // Assert
            Assert.IsTrue(actual1);
            Assert.IsFalse(actual2);
            Assert.IsTrue(actual3);
            Assert.IsFalse(actual4);
        }

        [TestMethod]
        public void TestIntEquals()
        {
            // Arrange
            var arrange = GenerateEntities(0, 1, 1);

            // Act            
            var actual1 = arrange[0].Equals(arrange[0]);
            var actual2 = arrange[0].Equals(null);
            var actual3 = arrange[1].Equals(arrange[2]);

            // Assert
            Assert.IsTrue(actual1);
            Assert.IsFalse(actual2);
            Assert.IsTrue(actual3);
        }

        #endregion

        [TestMethod]
        public void TestGetHashCode()
        {
            // Arrange
            var arrange1 = new Entity<int> { Id = 0 };
            var arrange2 = new Entity<int> { Id = 0 };
            var arrange3 = new Entity<string> { Id = null };

            // Act            
            var act1 = arrange1.GetHashCode();
            var act2 = arrange2.GetHashCode();
            var act3 = arrange3.GetHashCode();

            // Assert
            Assert.IsFalse(act1 == act2);
        }

        [TestMethod]
        public void TestIsNew()
        {
            // Arrange
            var arrange1 = new Entity<int> { Id = 0 };
            var arrange2 = new Entity<Guid>();
            var arrange5 = new Entity<Guid> { Id = Guid.NewGuid() };
            var arrange3 = new Entity<string> { Id = null };
            var arrange4 = new Entity<string> { Id = "" };

            // Assert
            Assert.IsTrue(arrange1.IsNew);
            Assert.IsTrue(arrange2.IsNew);
            Assert.IsTrue(arrange3.IsNew);
            Assert.IsFalse(arrange4.IsNew);
            Assert.IsFalse(arrange5.IsNew);
        }

        private IList<Entity<Type>> GenerateEntities<Type>(params Type[] values)
        {
            var entities = new List<Entity<Type>>();
            foreach (var id in values)
            {
                entities.Add(new Entity<Type> { Id = id });
            }
            return entities;
        }
    }
}
